package cn.ddiancan.xddcloud.psc.lookup.service;

import cn.ddiancan.xddcloud.common.entity.CommonResult;
import cn.ddiancan.xddcloud.psc.lookup.domain.LookupClassifyVO;
import cn.ddiancan.xddcloud.psc.lookup.feign.LookupRemoteService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class LookupService {

    @Value("${spring.application.name}")
    private String appName = "xddcloud-psc";

    private static final Cache<String, Object> levelOneCache =
        CacheBuilder.newBuilder().expireAfterAccess(30, TimeUnit.MINUTES).maximumSize(256).build();

    @Autowired
    private LookupRemoteService lookupRemoteService;

    @SuppressWarnings("unchecked")
    public CommonResult<LookupClassifyVO> findLookupByClassifyCode(String classifyCode) {
        String key = appName + classifyCode;
        return Optional.ofNullable((CommonResult<LookupClassifyVO>) levelOneCache.getIfPresent(key)).orElseGet(() -> {
            CommonResult<LookupClassifyVO> lookupByClassifyCode =
                lookupRemoteService.findLookupByClassifyCode(classifyCode, appName);
            Optional.ofNullable(lookupByClassifyCode).ifPresent(remoteResult -> {
                levelOneCache.put(key, remoteResult);
            });
            return lookupByClassifyCode;
        });
    }

    @SuppressWarnings("unchecked")
    public CommonResult<List<LookupClassifyVO>> getAllClassifies() {
        List<LookupClassifyVO> lookupClassifyVOList = (List<LookupClassifyVO>) levelOneCache.getIfPresent(appName);
        AtomicReference<List<LookupClassifyVO>> resultList = new AtomicReference<>(lookupClassifyVOList);
        if (CollectionUtils.isEmpty(lookupClassifyVOList)) {
            Optional.ofNullable(lookupRemoteService.getAllClassifies(appName)).ifPresent(remoteResult -> {
                List<LookupClassifyVO> remote = remoteResult.getData();
                if (!CollectionUtils.isEmpty(remote)) {
                    resultList.set(remote);
                    levelOneCache.put(appName, remote);
                }
            });
        }
        return CommonResult.success(resultList.get());
    }
}
